<template>
  <div class="chat-container flex-box flex-column">
    <div class="messages flex-item">
      <!-- 消息会被渲染到这里 -->
      <Message v-for="(m, i) in messages" :key="i" :message="m">
        <template slot-scope="scope">
          <div class="operation">
            <i
              class="el-icon-circle-close"
              @click="scope.data.abort = true"
            ></i>
            <i
              class="el-icon-edit"
              @click="newMessage = getContent(scope.data.content)"
            ></i>
            <i
              class="el-icon-document-copy"
              v-clipboard:copy="getContent(scope.data.content)"
            ></i>
            <i class="el-icon-refresh" @click="send(messages)"></i>
          </div>
        </template>
      </Message>
    </div>

    <div class="input-area flex-box flex-column">
      <div class="flex-box flex-between">
        <div class="input-area_left flex-item">
          <el-button
            size="small"
            icon="el-icon-setting"
            @click="showSettingDialog = true"
          ></el-button>
        </div>

        <div class="input-area_right">
          <el-select
            size="small"
            :value="config.model"
            placeholder="请选择模型"
            @change="handleChangeConfig($event, 'model')"
          >
            <el-option
              v-for="item in models"
              :key="item.model"
              :label="item.name"
              :value="item.model"
            >
            </el-option>
          </el-select>

          <el-button
            size="small"
            type="success"
            icon="el-icon-s-promotion"
            @click="sendMessage"
          ></el-button>
        </div>
      </div>

      <el-input
        resize="none"
        type="textarea"
        class="flex-item"
        v-model="newMessage"
        placeholder="发送消息..."
        @keypress.enter.native.prevent="sendMessage"
      />
    </div>

    <el-dialog
      width="600px"
      title="DeepSeek特定设置"
      :visible.sync="showSettingDialog"
    >
      <el-form label-position="top">
        <el-form-item label="API URL">
          <el-input
            :value="config.url"
            style="width: 100%"
            @input="handleChangeConfig($event, 'url')"
          ></el-input>
        </el-form-item>
        <el-form-item label="模型(model)">
          <el-select
            style="width: 100%"
            :value="config.model"
            placeholder="请选择模型"
            @change="handleChangeConfig($event, 'model')"
          >
            <el-option
              v-for="item in models"
              :key="item.model"
              :label="item.name"
              :value="item.model"
            >
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="上下文的消息数量上限">
          <el-slider
            :min="0"
            :max="20"
            show-input
            :step="2"
            style="width: 100%"
            :value="config.messageCount"
            @input="handleChangeConfig($event, 'messageCount')"
          ></el-slider>
        </el-form-item>

        <el-form-item label="严谨与想象(Temperature)">
          <el-slider
            :min="0"
            :max="2"
            show-input
            :step="0.01"
            style="width: 100%"
            :value="config.temperature"
            @input="handleChangeConfig($event, 'temperature')"
          ></el-slider>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
import Message from "../components/message.vue";

export default {
  components: {
    Message,
  },
  data() {
    return {
      messages: [],
      newMessage: "",
      showSettingDialog: false,
    };
  },
  computed: {
    ...mapGetters(["models", "config"]),
  },
  methods: {
    getContent(content) {
      const startIndex = content.indexOf("</think>");
      if (startIndex > -1) {
        return content.substr(startIndex + "</think>".length).trim();
      }
      return "";
    },
    handleChangeConfig(value, key) {
      this.$store.commit("setConfig", { value, key });
      if (key === "url") {
        this.$store.dispatch("getModels");
      }
    },
    send(messages) {
      // 这里需要调用你的 DeepSeek 模型服务接口
      return fetch(`${this.config.url}/api/chat`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          messages,
          stream: true,
          model: this.config.model,
          options: { temperature: this.config.temperature },
        }),
      });
    },
    async sendMessage() {
      const message = this.newMessage.trim();
      this.newMessage = "";
      if (!message) return;

      // 添加消息到聊天记录
      this.messages.push({
        content: message,
        role: "user", // 可以根据角色不同设置为'bot'或'user'
        timestamp: new Date().toLocaleString(),
      });

      // 调用 DeepSeek 模型服务接口
      const response = await this.send(
        this.messages.slice(
          Math.max(0, this.messages.length - this.config.messageCount - 1)
        )
      );

      if (response.error) {
        console.error("请求失败:", response.error);
      } else {
        // let text = await response.text();
        const reader = response.body.getReader(); // 获取Reader对象
        const decoder = new TextDecoder(); // 创建TextDecoder用于解码流中的文本数据
        let botResponse = {
          content: "",
          role: "bot",
          abort: false,
          timestamp: new Date().toLocaleString(),
        };
        this.messages.push(botResponse);

        return reader.read().then(function processResult({ done, value }) {
          if (done) {
            return; // 流结束
          }
          if (botResponse.abort) {
            return;
          }

          const result = JSON.parse(decoder.decode(value, { stream: true }));
          botResponse.content += result.message.content;
          console.log(botResponse.content);
          return reader.read().then(processResult); // 递归读取下一个数据块
        });
      }
    },
  },
};
</script>

<style lang="scss">
.chat-container {
  margin: 0 auto;
  padding: 0px;
  height: 100%;

  .message-container:hover .operation {
    display: block;
  }

  .operation {
    box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);
    display: none;
    position: absolute;
    left: 92px;
    padding: 4px;
    bottom: -6px;

    background: #fff;
    border-radius: 4px;

    i {
      &:first-child {
        color: #ee0000;
      }

      margin: 0 4px;
      cursor: pointer;
    }
  }
}

.messages {
  overflow-y: auto;
}

.input-area {
  height: 200px;
  border-top: 1px solid #dcdfe6;

  &_left {
    .el-button {
      border: none;
    }
  }

  .el-select {
    .el-input__inner {
      border: none;
    }
  }

  .el-textarea__inner {
    border: none;
    height: 100%;
  }

  .el-button {
    font-size: 18px;
    padding: 6px 10px;
  }
}
</style>
